#include "doublelinklist1.h"
int main(int argc, char const *argv[])
{
    linkNode *H =list_Create();//创建一个双向链表
    //通过尾插法插入数据
    list_tail_insert(H,1);
    list_tail_insert(H,2);
    list_tail_insert(H,3);
    //遍历
    list_show(H);
    //通过头插法插入数据
    list_head_insert(H,5);
    list_head_insert(H,6);
    list_head_insert(H,7);
        //遍历
     list_show(H);
     list_insert(H,100,4);
     list_show(H);
     list_insert(H,101,7);
     list_show(H);
     list_insert(H,120,9);
     list_show(H);
     printf("总结点数为%d,不含头结点结点数：%d\n",list_length_head(H),list_DataNode_length(H));
     //删除结点测试
     list_delete(H,1);
     list_show(H);
     list_delete(H,7);
     list_show(H);
     list_delete(H,7);
     list_show(H);
//销毁
    H=list_free(H);
    list_show(H);
    free(H);

    return 0;
}

//创建一个空链表
pLinklist list_Create()
{
    pLinklist Head=(pLinklist)malloc(sizeof(linkNode));//创建一个头节点
    if(Head==NULL)
    {
        printf("MALLOC FAILED\n");
        return NULL;
    }
    //头节点不用来存数据 只用来指向下一个节点的地址
    Head->data=0;
    Head->next=Head->prior= NULL;//无数据  也就不存在上一个结点和下一个节点
    return Head;
}
 

//判断是否为空链表  是空链表返回-1  不是返回0
int empty(pLinklist H)
{
    if (H==NULL||H->next==NULL)
    {
       return -1;
    }
    return 0;
}
//遍历  双向链表
int list_show(pLinklist H)
{
    //头节点没有数据
    if(H==NULL)
    {
        printf("linklist is NULL\n");
        return -1;
    }
    pLinklist p_head=H->next;//从头节点下一个结点开始
    while (p_head)//最后一个结点（尾节点）是有数据的 只是指针域为NULL
    {
        printf("%d\t",p_head->data);
        p_head=p_head->next;
    }
    printf("\n");
    // printf("前驱遍历：\n");
    // p_head=H->next;//从头节点下一个结点开始
    // while (p_head->next)//
    // {
    //     p_head=p_head->next;
    // }
    // //此时phead到了最后一个结点
    // while (p_head->prior)//p_head是头结点就结束循环
    // {
    //     printf("%d\t",p_head->data);
    //     p_head=p_head->prior;//指向前驱
    // } 
    // printf("\n");
    return 1;
}
//头插
int list_head_insert(pLinklist H, data_type value)
{
    if (H==NULL)
    {
       return -1;
    }
    //动态分配一段内存
     //为新数据创建一个结点  新节点
     pLinklist newNode=(pLinklist)malloc(sizeof(linkNode));
     if(newNode==NULL)
     {
         printf("newNode is NULL\n");
         return -1;
     }
     newNode->data=value;//新节点的数据
     newNode->prior=newNode->next=NULL;//指针域
     //带头结点的双向链表 数据插入在头结点之后
     //让新结点的后继指向H->next
     newNode->next=H->next;
     H->next->prior=newNode;//原来H的下一个结点的前驱  指向新结点
     H->next=newNode;
     newNode->prior= H;

    
}
//尾插
int list_tail_insert(pLinklist H, data_type value)
{
    if (H==NULL)
    {
       return -1;
    }
    //动态分配一段内存
     //为新数据创建一个结点  新节点
     pLinklist newNode=(pLinklist)malloc(sizeof(linkNode));
     if(newNode==NULL)
     {
         printf("newNode is NULL\n");
         return -1;
     }
     newNode->data=value;//新节点的数据
     newNode->prior=newNode->next=NULL;//指针域
     //将当前的新的结点插入到头结点后面 
     pLinklist phead=H;
     while (phead->next)//pjead是尾结点
     {
        phead=phead->next;
     }
     //phead 是尾节点
     phead->next=newNode;
     newNode->prior=phead;
     
}
//获得指定位置的结点
pLinklist list_get(pLinklist H, int pos)//通过pos 获得第pos个位置的结点
{
    if(H==NULL)
    {
        printf("linklist is NULL\n");
        return NULL;
    }
    if(pos<1)//pos从1开始  为什么从1开始？因为头节点没有数据
    {
        printf("pos is error\n");
        return NULL;
    }
    pLinklist p_head=H;//p_head是一个"替死鬼"
    int i;//找第pos个位置
    for(i=0;i<pos;i++)
    {
        p_head=p_head->next;
        //有可能pos位置越界  超过链表的长度
        if(p_head==NULL)
        {
            printf("pos is error too large\n");
            break;
        }  
    }
    //当前p_head就是我要找的结点
    return p_head;
}
//指定位置插入
int list_insert(pLinklist H, data_type value, int pos)//将value插入到第pos结点之前
{
    if (H==NULL)
    {
       return -1;
    }
    if(pos<1)//pos从1开始  为什么从1开始？因为头节点没有数据
    {
        printf("pos is error\n");
        return -1;
    }
    //动态分配一段内存
     //为新数据创建一个结点  新节点
     pLinklist newNode=(pLinklist)malloc(sizeof(linkNode));
     if(newNode==NULL)
     {
         printf("newNode is NULL\n");
         return -1;
     }
     newNode->data=value;//新节点的数据
     newNode->prior=newNode->next=NULL;//指针域
     //找到pos位置的结点
     pLinklist phead=list_get(H,pos);
     if(phead==NULL)
     {
        printf("data insert pos is error\n");
        return -1;
     }
     //将新节点与第pos个结点的前驱结点连接
     phead->prior->next=newNode;//pos的前一个结点的后继指向新节点
     newNode->prior=phead->prior;//新节点的前驱 指向pos的前一个结点
     //新节点与phead连接
     newNode->next=phead;
     phead->prior=newNode;
     return 0;  
}
//销毁链表
pLinklist list_free(pLinklist H)
{
    if (H ==NULL)
    {
        return NULL;
    }
    linkNode *p_head=H;//p_head是一个"替死鬼" 指向“头”节点
    while(p_head!=NULL)//p_head将会指向尾节点的指针域为NULL  就结束释放
    {
        linkNode *p=p_head->next;//p指向p_head的下一个结点  后面的数据
        free(p_head);//释放p_head 释放当前头节点
        p_head=p;//更新头节点

    }
    return NULL;
}
//删除某一个位置上的结点
int list_delete(pLinklist H, int pos)
{
    if (H ==NULL)
    {
        return -1;
    }
    if(pos<1)//pos从1开始  为什么从1开始？因为头节点没有数据
    {
        printf("pos is error\n");
        return -1;
    }
     //找到pos位置的结点
     pLinklist phead=list_get(H,pos);
     if(phead==NULL)
     {
        printf("data insert pos is error\n");
        return -1;
     }
     if (pos==list_DataNode_length(H))
     {
        phead->prior->next=NULL;
        free(phead);
        return 0;
     }
     
     //删除第pos结点
     phead->next->prior=phead->prior;
     phead->prior->next=phead->next;
     //释放phead
     memset(phead,0,sizeof(linkNode));
     free(phead);
     return 0;

}
//求链表的总结点数（包括头结点在内）
int list_length_head(pLinklist H)
{
   if (H==NULL)//
   {
    return -1;
   }

   int i=0;
   pLinklist p_head=H;
   //总结点数
   while(p_head)
   {
    i++;
    p_head=p_head->next;
   }
   return i;   
}

//求链表的数据结点数（不包括头结点在内）
int list_DataNode_length(pLinklist H)
{
   if (H==NULL)//
   {
    return -1;
   }

   int i=0;
   pLinklist p_head=H->next;
   //总结点数
   while(p_head)
   {
    i++;
    p_head=p_head->next;
   }
   return i;   
}